package dev.ece.core.cells.model.base;

import org.lwjgl.opengl.GL11;

import dev.ece.core.cells.model.AbstractModel;
import dev.ece.core.light.Material;
import dev.ece.core.texture.FBOS;
import dev.ece.core.vertex.VAO;
import dev.ece.core.vertex.VBO;
import dev.ece.util.lib.Vector2f;
import dev.ece.util.lib.Vector3f;
import dev.ece.util.tools.Camera;

public class SquareModel extends AbstractModel<Object> {
	
	private Vector3f[] vertice;
	
	private Vector2f[] uv;
	
	private VBO verticeVBO;
	
	private VBO uvVBO;
	
	private VAO vao;
	
	private Material material;
	
	private float width;
	
	private float height;
	
	public SquareModel(float width, float height) {
		this.width = width;
		this.height = height;
		float hWidth = width / 2;
		float hHeight = height / 2;
		vertice = new Vector3f[4];
		vertice[0] = new Vector3f(- hWidth, hHeight, 0);
		vertice[1] = new Vector3f(- hWidth, - hHeight, 0);
		vertice[2] = new Vector3f(hWidth, hHeight, 0);
		vertice[3] = new Vector3f(hWidth, - hHeight, 0);
		uv = new Vector2f[4];
		uv[0] = new Vector2f(0, 0);
		uv[1] = new Vector2f(0, 1);
		uv[2] = new Vector2f(1, 0);
		uv[3] = new Vector2f(1, 1);
		material = new Material();
		material.getDiffuse().set(0.2f, 0.2f, 0.2f);
		material.getSpecular().set(0.6f, 0.6f, 0.6f);
		material.setShininess(64);
		
		setup();
	}

	protected void setup() {
		verticeVBO = VBO.newInstance(vertice);
		uvVBO = VBO.newInstance(uv);
		VBO.unbind();
	}
	
	public Material getMaterial() {
		return material;
	}

	@Override
	public void destroy() {
		if(vao != null) {
			vao.destroy();
		}
		vao = null;
		vertice = null;
		uv = null;
	}

	@Override
	public void onInitialize() {
		vao = new VAO();
		vao.bind();
		vao.bindVertexArrayBuffer(verticeVBO, 3);
		vao.bindVertexArrayBuffer(uvVBO, 2);
		vao.finish();
		
		verticeVBO = null;
		uvVBO = null;
	}

	

	@Override
	public void onRender(Camera camera, Object value) {
		vao.bind();
		GL11.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, 4);
	}

	@Override
	public void onRenderDepthMap(Camera camera, Object value) {
		this.onRender(camera, value);
	}

	@Override
	public void onRenderAlpha(FBOS defer, Camera camera, Object value) {}

	public Vector3f[] getVertice() {
		return vertice;
	}

	public Vector2f[] getUv() {
		return uv;
	}
	
	public float getWidth() {
		return width;
	}

	public float getHeight() {
		return height;
	}

}
